#include<input_manager.h>
#include <pthread.h>


static PInputDevOpr g_ptInputDevHead = NULL;

static pthread_mutex_t g_tMutex  = PTHREAD_MUTEX_INITIALIZER;
static pthread_cond_t    g_tConVar = PTHREAD_COND_INITIALIZER;


/* start of 环形缓冲区*/

#define BUFFER_LEN 20

static int g_iRead = 0;
static int g_iWrite = 0;
static InputEvent InputEventBuffer[BUFFER_LEN];

//判断是否满，写的下一个是读
static int IsInputEventBufferFull(void)
{
	return ((g_iWrite + 1) % BUFFER_LEN == g_iRead);
}

//判断是否空，读等于写
static int IsInputEventBufferEmpty(void)
{
	return (g_iWrite == g_iRead);
}

//写
static int PutInputEventToBuffer(PInputEvent ptEvent)
{
	if(!IsInputEventBufferFull())
	{
		InputEventBuffer[g_iWrite] = *ptEvent;
		g_iWrite = (g_iWrite + 1) % BUFFER_LEN;
		return 1;
	}
	else
	{
		return 0;
	}
}

//读
static int GetInputEventFromBuffer(PInputEvent ptEvent)
{
	if(!IsInputEventBufferEmpty())
	{
		*ptEvent = InputEventBuffer[g_iRead];
		g_iRead = (g_iRead + 1) % BUFFER_LEN;
		return 1;
	}
	else
	{
		return 0;
	}
}

/* end of 环形缓冲区*/


void RegisterInputDev(PInputDevOpr ptInputDevOpr)
{
	ptInputDevOpr->ptNext = g_ptInputDevHead;
	g_ptInputDevHead = ptInputDevOpr;
}

void InputStystemRegister(void)
{
	/* register touchscreen */
	extern void TouchScreenRegister(void);
	TouchScreenRegister();
	
	/* register netinput */
	extern void NetDeviceRegister(void);
	NetDeviceRegister();
}


//存数据
static void* input_recv_thread_func(void* data)
{
	int ret;
	PInputDevOpr tInputEventOpr = (PInputDevOpr)data;
	InputEvent tInputEvent;

	while (1)
	{
	    ret = tInputEventOpr->GetInputEvent(&tInputEvent);

		/* 有数据 */
		if(!ret)
		{
			pthread_mutex_lock(&g_tMutex);
			PutInputEventToBuffer(&tInputEvent);

			/* 唤醒等待数据的线程 */
			pthread_cond_signal(&g_tConVar); /* 通知接收线程 */
			pthread_mutex_unlock(&g_tMutex);
		}
	}

	return NULL;
}


int InputStystemInit(void)
{
	int ret;
	PInputDevOpr pTemp = g_ptInputDevHead;
	pthread_t tid;

	/* for each inputdevice, init, pthread_create */
	while(pTemp)
	{
		/* init device */
		ret = pTemp->DeviceInit();
		if(!ret)
		{
			/* pthread_create */
			ret = pthread_create(&tid, NULL, input_recv_thread_func, pTemp);
			if (ret)
			{
				printf("pthread_create err!\n");
				return -1;
			}
		}
		pTemp = pTemp->ptNext;
	}
	return 0;
}

int GetInputEvent(PInputEvent ptInputEvent)
{
	int ret;
	InputEvent tEvent;
	
	pthread_mutex_lock(&g_tMutex);

	if(GetInputEventFromBuffer(&tEvent))
	{
		//有数据
		*ptInputEvent = tEvent;
		pthread_mutex_unlock(&g_tMutex);
		return 0;
	}
	else
	{
		//休眠
		pthread_cond_wait(&g_tConVar, &g_tMutex);	
		if(GetInputEventFromBuffer(&tEvent))
		{
			//有数据
			*ptInputEvent = tEvent;
			ret = 0;
		}
		else
		{
			ret = -1;
		}
		pthread_mutex_unlock(&g_tMutex);
	}
	return ret;
}



	




